package com.yc.pay.service.impl;

import com.yc.pay.api.enums.PayChannelEnums;
import com.yc.pay.api.enums.PayWayEnums;
import com.yc.pay.api.req.NetBankPayReq;
import com.yc.pay.api.req.PayQueryReq;
import com.yc.pay.api.resp.RespVo;
import com.yc.pay.api.resp.TradeQueryRespData;
import com.yc.pay.iclient.IAlipayClient;
import com.yc.pay.mapper.PaySerialMapper;
import com.yc.pay.model.PaySerial;
import com.yc.pay.service.IPaySerialService;
import com.yc.pay.api.utils.IdWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 支付流水实现类
 */
@Service
public class PaySerialServiceImpl implements IPaySerialService {

    @Autowired
    private PaySerialMapper paySerialMapper;

    private Logger logger = LoggerFactory.getLogger(PaySerialServiceImpl.class);


/*    @Autowired
    private RestTemplate restTemplate;*/

    @Autowired
    private IAlipayClient alipayClient;


    /**
     * 创建流水, 问题一：避免重复支付。
     *
     * 线程2 ，线程3 等待获取锁
     *
     * synchronized 只能保证一个线程在一台服务器上，能获取到锁，但是多台服务器，可能有多个线程同时获取锁
     * 分布式锁。
     *
     */
    @Override
    public  PaySerial createPaySerial(NetBankPayReq netBankPayReq) {
        //线程1 获取锁
        List<PaySerial> paySerialList = paySerialMapper.queryByMchOrderNo(netBankPayReq.getOrderNo());
        if (!CollectionUtils.isEmpty(paySerialList)){
            logger.info("订单号：{},创建流水失败：已经存在状态为：{}",netBankPayReq.getOrderNo(), paySerialList.get(0).getStatus());
            return null;
        }

        PaySerial paySerial = new PaySerial();
        paySerial.setMchOrderId(netBankPayReq.getOrderNo());
        paySerial.setOrderSubject(netBankPayReq.getSubject());
        paySerial.setPayAmt(new BigDecimal(netBankPayReq.getAmount()));
        paySerial.setPayWay(netBankPayReq.getPayWay());
        paySerial.setCreateTime(new Date());
        paySerial.setCreateBy("system");
        //生成全局唯一id
        IdWorker idWorker = new IdWorker(1,1,1);
        paySerial.setPaySerialNo(String.valueOf(idWorker.nextId()));
        paySerialMapper.insertSelective(paySerial);

        return paySerial;
    }
    // 线程一释放锁

    @Override
    public PaySerial queryByOutTradeNo(String outTradeNo) {
        return paySerialMapper.queryByPaySerialNo(outTradeNo);
    }

    @Override
    public void updatePaySerial(PaySerial paySerial) {

        paySerialMapper.updateByPrimaryKeySelective(paySerial);

    }

    @Override
    public RespVo<Object> tradeQuery(PayQueryReq payQueryReq) {

        PaySerial paySerial =  paySerialMapper.queryByPaySerialNo(payQueryReq.getPaySerialNo());

        if (ObjectUtils.isEmpty(paySerial)){
            return  RespVo.returnFailRespVo("不存在");
        }

        if("0".equals(paySerial.getStatus()) || "1".equals(paySerial.getStatus())){

            //返回支付成功 或者支付失败

            return RespVo.returnSuccessRespVo("");
        }

        // 调用银行查询接口

        if (PayChannelEnums.ALIPAY.getCode().equals(payQueryReq.getPayChannel())){

            //调用接口 .springCloud 调用

//            String url = "http://ALIPAY-FRONT/alipay/query?outTradeNo="+ "202101041449";
//
//            RespVo respVo = restTemplate.getForObject(url,RespVo.class);

//            System.out.println("----------respVo--------" + respVo);

            RespVo respVo =  alipayClient.alipayTradeQuery("202101041449");

           TradeQueryRespData respData = (TradeQueryRespData)respVo.getData();
           if (ObjectUtils.isEmpty(respData)){
               return null;
           }

           if ("TRADE_SUCCESS".equals(respData.getStatus()) || "TRADE_SUCCESS".equals(respData.getStatus()) ){
               //更新数据库 状态成功

               //封装返回对象
           } else  if ("TRADE_CLOSE".equals(respData.getStatus())){

               //更新数据库失败
               //封装返回对象
           } else {
               // 不更新数据库

               // 知返会状态给业务系统

               return null;
           }






        }else if(PayChannelEnums.WECHAT.getCode().equals(payQueryReq.getPayChannel())){

            //调用接口

        }






        return null;
    }

    @Override
    public RespVo<Object> tradeClose(PayQueryReq payQueryReq) {
        //1. 查询交易是否存在

        //2. 判断状态是否。1,2

        //3.调用前置服务的交易关闭接口

        //4. 前置服务返回关闭成功，更新状态。交易失败

        //5. 封装对象返回


        return null;
    }

    public static void main(String[] args) {
        System.out.println(UUID.randomUUID().toString().replaceAll("-",""));

         new BigDecimal("1111111111111111111111111111111111");
    }
}
